package cn.ifanmi.findme.adapter;

import java.io.File;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.text.SpannableString;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import cn.ifanmi.findme.R;
import cn.ifanmi.findme.bean.Person;
import cn.ifanmi.findme.bean.User;
import cn.ifanmi.findme.dbService.PersonService;
import cn.ifanmi.findme.em.AlertDialogActivity;
import cn.ifanmi.findme.em.BaiduMapActivity;
import cn.ifanmi.findme.em.ContextMenuActivity;
import cn.ifanmi.findme.em.ImageCache;
import cn.ifanmi.findme.em.ImageUtils;
import cn.ifanmi.findme.em.LoadImageTask;
import cn.ifanmi.findme.em.LoadVideoImageTask;
import cn.ifanmi.findme.em.ShowBigImageActivity;
import cn.ifanmi.findme.em.ShowNormalFileActivity;
import cn.ifanmi.findme.em.ShowVideoActivity;
import cn.ifanmi.findme.em.VoicePlayClickListener;
import cn.ifanmi.findme.fanconst.IntentString;
import cn.ifanmi.findme.fanconst.NormalString;
import cn.ifanmi.findme.listener.PersonDataListener;
import cn.ifanmi.findme.util.ImageViewUtil;
import cn.ifanmi.findme.util.SPUtil;
import cn.ifanmi.findme.util.StringUtil;
import cn.ifanmi.findme.util.ToastUtil;

import com.easemob.EMCallBack;
import com.easemob.chat.EMChatManager;
import com.easemob.chat.EMConversation;
import com.easemob.chat.EMMessage;
import com.easemob.chat.EMMessage.ChatType;
import com.easemob.chat.EMMessage.Type;
import com.easemob.chat.FileMessageBody;
import com.easemob.chat.ImageMessageBody;
import com.easemob.chat.LocationMessageBody;
import com.easemob.chat.NormalFileMessageBody;
import com.easemob.chat.TextMessageBody;
import com.easemob.chat.VideoMessageBody;
import com.easemob.chat.VoiceMessageBody;
import com.easemob.exceptions.EaseMobException;
import com.easemob.util.DateUtils;
import com.easemob.util.FileUtils;
import com.easemob.util.LatLng;
import com.easemob.util.TextFormater;

public class ChatAdapter extends BaseAdapter {

	private Activity activity;
	private String friendId;
	private String friendPhoto;
	private String myId;
	private String myPhoto;
	private EMConversation conversation;
	private LayoutInflater inflater;
	private final static String TAG = "chat_adapter";
	
	public ChatAdapter(Activity activity, String friendId, String friendPhoto) {
		this.activity = activity;
		this.friendId = friendId;
		this.friendPhoto = friendPhoto;
		myId = SPUtil.getUser(activity, User.ID);
		PersonService service = new PersonService(activity);
		Person person = service.getPersonById(myId);
		if (person != null) {
			myPhoto = person.getPhoto();
		}
		service.closeDBHelper();
		conversation = EMChatManager.getInstance().getConversation(friendId);
		inflater = LayoutInflater.from(activity);
	}

	@Override
	public int getCount() {
		return conversation.getMsgCount();
	}

	@Override
	public EMMessage getItem(int position) {
		return conversation.getMessage(position);
	}

	@Override
	public long getItemId(int position) {
		return position;
	}

	@SuppressLint("CutPasteId")
	@Override
	public View getView(final int position, View convertView, ViewGroup parent) {
		final EMMessage message = getItem(position);
		ChatType chatType = message.getChatType();
		ViewHolder holder = null;
		if (convertView == null) {
			holder = new ViewHolder();
			convertView = createViewByMessage(message, position);
			if (message.getType() == EMMessage.Type.IMAGE) {
				try {
					holder.iv = ((ImageView) convertView.findViewById(R.id.iv_sendPicture));
					holder.img_photo = (ImageView) convertView.findViewById(R.id.iv_userhead);
					holder.tv = (TextView) convertView.findViewById(R.id.percentage);
					holder.pb = (ProgressBar) convertView.findViewById(R.id.progressBar);
					holder.staus_iv = (ImageView) convertView.findViewById(R.id.msg_status);
					holder.txt_nickname = (TextView) convertView.findViewById(R.id.tv_userid);
				} catch (Exception e) {
					
				}
			} else if (message.getType() == EMMessage.Type.TXT) {
				try {
					holder.pb = (ProgressBar) convertView.findViewById(R.id.pb_sending);
					holder.staus_iv = (ImageView) convertView.findViewById(R.id.msg_status);
					holder.img_photo = (ImageView) convertView.findViewById(R.id.iv_userhead);
					holder.tv = (TextView) convertView.findViewById(R.id.tv_chatcontent);
					holder.txt_nickname = (TextView) convertView.findViewById(R.id.tv_userid);
				} catch (Exception e) {
					
				}
			} else if (message.getType() == EMMessage.Type.VOICE) {
				try {
					holder.iv = ((ImageView) convertView.findViewById(R.id.iv_voice));
					holder.img_photo = (ImageView) convertView.findViewById(R.id.iv_userhead);
					holder.tv = (TextView) convertView.findViewById(R.id.tv_length);
					holder.pb = (ProgressBar) convertView.findViewById(R.id.pb_sending);
					holder.staus_iv = (ImageView) convertView.findViewById(R.id.msg_status);
					holder.txt_nickname = (TextView) convertView.findViewById(R.id.tv_userid);
					holder.iv_read_status = (ImageView) convertView.findViewById(R.id.iv_unread_voice);
				} catch (Exception e) {
					
				}
			} else if (message.getType() == EMMessage.Type.LOCATION) {
				try {
					holder.img_photo = (ImageView) convertView.findViewById(R.id.iv_userhead);
					holder.tv = (TextView) convertView.findViewById(R.id.tv_location);
					holder.pb = (ProgressBar) convertView.findViewById(R.id.pb_sending);
					holder.staus_iv = (ImageView) convertView.findViewById(R.id.msg_status);
					holder.txt_nickname = (TextView) convertView.findViewById(R.id.tv_userid);
				} catch (Exception e) {
					
				}
			} else if (message.getType() == EMMessage.Type.VIDEO) {
				try {
					holder.iv = ((ImageView) convertView.findViewById(R.id.chatting_content_iv));
					holder.img_photo = (ImageView) convertView.findViewById(R.id.iv_userhead);
					holder.tv = (TextView) convertView.findViewById(R.id.percentage);
					holder.pb = (ProgressBar) convertView.findViewById(R.id.progressBar);
					holder.staus_iv = (ImageView) convertView.findViewById(R.id.msg_status);
					holder.size = (TextView) convertView.findViewById(R.id.chatting_size_iv);
					holder.timeLength = (TextView) convertView.findViewById(R.id.chatting_length_iv);
					holder.playBtn = (ImageView) convertView.findViewById(R.id.chatting_status_btn);
					holder.container_status_btn = (LinearLayout) convertView.findViewById(R.id.container_status_btn);
					holder.txt_nickname = (TextView) convertView.findViewById(R.id.tv_userid);
				} catch (Exception e) {
					
				}
			} else if (message.getType() == EMMessage.Type.FILE) {
				try {
					holder.img_photo = (ImageView) convertView.findViewById(R.id.iv_userhead);
					holder.tv_file_name = (TextView) convertView.findViewById(R.id.tv_file_name);
					holder.tv_file_size = (TextView) convertView.findViewById(R.id.tv_file_size);
					holder.pb = (ProgressBar) convertView.findViewById(R.id.pb_sending);
					holder.staus_iv = (ImageView) convertView.findViewById(R.id.msg_status);
					holder.tv_file_download_state = (TextView) convertView.findViewById(R.id.tv_file_state);
					holder.ll_container = (LinearLayout) convertView.findViewById(R.id.ll_file_container);
					holder.tv = (TextView)convertView.findViewById(R.id.pb_sending);
				} catch (Exception e) {
					
				}
			}
			convertView.setTag(holder);
		} else {
			holder = (ViewHolder) convertView.getTag();
		}

		// 群聊时，显示接收的消息的发送人的名称
		if (chatType == ChatType.GroupChat && message.direct == EMMessage.Direct.RECEIVE)
			// demo用username代替nick
			holder.txt_nickname.setText(message.getFrom());

		// 如果是发送的消息并且不是群聊消息，显示已读textview
		if (message.direct == EMMessage.Direct.SEND && chatType != ChatType.GroupChat) {
			holder.tv_ack = (TextView) convertView.findViewById(R.id.tv_ack);
			if (holder.tv_ack != null) {
				if (message.isAcked) {
					holder.tv_ack.setVisibility(View.VISIBLE);
				} else {
					holder.tv_ack.setVisibility(View.INVISIBLE);
				}
			}
		} else {
			// 如果是文本或者地图消息并且不是group messgae，显示的时候给对方发送已读回执
			if ((message.getType() == Type.TXT || message.getType() == Type.LOCATION) && !message.isAcked
					&& chatType != ChatType.GroupChat) {
				try {
					// 发送已读回执
					message.isAcked = true;
					EMChatManager.getInstance().ackMessageRead(message.getFrom(), message.getMsgId());
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}

		switch (message.getType()) {
		// 根据消息type显示item
		case IMAGE:
			handleImageMessage(message, holder, position, convertView);
			break;
		case TXT:
			handleTextMessage(message, holder, position);
			break;
		case LOCATION:
			handleLocationMessage(message, holder, position, convertView);
			break;
		case VOICE:
			handleVoiceMessage(message, holder, position, convertView);
			break;
		case VIDEO:
			handleVideoMessage(message, holder, position, convertView);
			break;
		case FILE:
			handleFileMessage(message, holder, position, convertView);
			break;
		default:
			// not supported
		}

		if (message.direct == EMMessage.Direct.SEND) {
			String smallUrl = StringUtil.getSmallPhoto(myPhoto, NormalString.SmallPhoto.PERSON_CHAT);
			ImageViewUtil.displayCircleImageView(activity, holder.img_photo, smallUrl);
			holder.img_photo.setOnClickListener(new PersonDataListener(activity, myId));
			View statusView = convertView.findViewById(R.id.msg_status);
			statusView.setOnClickListener(new OnClickListener() {
				public void onClick(View v) {
					// 显示重发消息的自定义AlertActivity
					Intent intent = new Intent(activity, AlertDialogActivity.class);
					intent.putExtra(IntentString.Extra.ALERT_MESSAGE, activity.getString(R.string.confirm_resend));
					intent.putExtra(IntentString.Extra.ALERT_TITLE, activity.getString(R.string.resend));
					intent.putExtra(IntentString.Extra.ALERT_CANCLE, true);
					intent.putExtra(IntentString.Extra.ALERT_POSITION, position);
					if (message.getType() == EMMessage.Type.TXT)
						activity.startActivityForResult(intent, IntentString.RequestCode.CHAT_ALERT_TEXT);
					else if (message.getType() == EMMessage.Type.VOICE)
						activity.startActivityForResult(intent, IntentString.RequestCode.CHAT_ALERT_VOICE);
					else if (message.getType() == EMMessage.Type.IMAGE)
						activity.startActivityForResult(intent, IntentString.RequestCode.CHAT_ALERT_PICTURE);
					else if (message.getType() == EMMessage.Type.LOCATION)
						activity.startActivityForResult(intent, IntentString.RequestCode.CHAT_ALERT_LOCATION);
					else if (message.getType() == EMMessage.Type.FILE)
						activity.startActivityForResult(intent, IntentString.RequestCode.CHAT_ALERT_FILE);
					else if (message.getType() == EMMessage.Type.VIDEO)
						activity.startActivityForResult(intent, IntentString.RequestCode.CHAT_ALERT_VIDEO);
				}
			});
		} else if (message.direct == EMMessage.Direct.RECEIVE) {
			String smallUrl = StringUtil.getSmallPhoto(friendPhoto, NormalString.SmallPhoto.PERSON_CHAT);
			ImageViewUtil.displayCircleImageView(activity, holder.img_photo, smallUrl);
			holder.img_photo.setOnClickListener(new PersonDataListener(activity, friendId));
		}

		TextView timestamp = (TextView) convertView.findViewById(R.id.timestamp);
		if (position == 0) {
			timestamp.setText(DateUtils.getTimestampString(new Date(message.getMsgTime())));
			timestamp.setVisibility(View.VISIBLE);
		} else {
			if (DateUtils.isCloseEnough(message.getMsgTime(), conversation.getMessage(position - 1).getMsgTime())) {
				timestamp.setVisibility(View.GONE);
			} else {
				timestamp.setText(DateUtils.getTimestampString(new Date(message.getMsgTime())));
				timestamp.setVisibility(View.VISIBLE);
			}
		}
		return convertView;
	}
	
	public class ViewHolder {
		ImageView iv;
		TextView tv;
		ProgressBar pb;
		ImageView staus_iv;
		ImageView img_photo;
		TextView txt_nickname;
		ImageView playBtn;
		TextView timeLength;
		TextView size;
		LinearLayout container_status_btn;
		LinearLayout ll_container;
		ImageView iv_read_status;
		TextView tv_ack;
		TextView tv_file_name;
		TextView tv_file_size;
		TextView tv_file_download_state;
	}
	
	@Override
	public int getViewTypeCount() {
		return NormalString.ChatViewType.COUNT;
	}
	
	@Override
	public int getItemViewType(int position) {
		EMMessage message = conversation.getMessage(position);
		if (message.getType() == EMMessage.Type.TXT) {
			return message.direct == EMMessage.Direct.RECEIVE ? 
					NormalString.ChatViewType.RECV_TXT : NormalString.ChatViewType.SENT_TXT;
		}
		if (message.getType() == EMMessage.Type.IMAGE) {
			return message.direct == EMMessage.Direct.RECEIVE ? 
					NormalString.ChatViewType.RECV_IMAGE : NormalString.ChatViewType.SENT_IMAGE;
		}
		if (message.getType() == EMMessage.Type.LOCATION) {
			return message.direct == EMMessage.Direct.RECEIVE ? 
					NormalString.ChatViewType.RECV_LOCATION : NormalString.ChatViewType.SENT_LOCATION;
		}
		if (message.getType() == EMMessage.Type.VOICE) {
			return message.direct == EMMessage.Direct.RECEIVE ? 
					NormalString.ChatViewType.RECV_VOICE : NormalString.ChatViewType.SENT_VOICE;
		}
		if (message.getType() == EMMessage.Type.VIDEO) {
			return message.direct == EMMessage.Direct.RECEIVE ? 
					NormalString.ChatViewType.RECV_VIDEO : NormalString.ChatViewType.SENT_VIDEO;
		}
		if (message.getType() == EMMessage.Type.FILE) {
			return message.direct == EMMessage.Direct.RECEIVE ? 
					NormalString.ChatViewType.RECV_FILE : NormalString.ChatViewType.SENT_FILE;
		}
		return NormalString.ChatViewType.INVALID;
	}
	
	private View createViewByMessage(EMMessage message, int position) {
		switch (message.getType()) {
		case LOCATION:
			return message.direct == EMMessage.Direct.RECEIVE ? 
					inflater.inflate(R.layout.row_received_location, null) : 
						inflater.inflate(R.layout.row_sent_location, null);
		case IMAGE:
			return message.direct == EMMessage.Direct.RECEIVE ? 
					inflater.inflate(R.layout.row_received_picture, null) : 
						inflater.inflate(R.layout.row_sent_picture, null);

		case VOICE:
			return message.direct == EMMessage.Direct.RECEIVE ? 
					inflater.inflate(R.layout.row_received_voice, null) : 
						inflater.inflate(R.layout.row_sent_voice, null);
					
		case VIDEO:
			return message.direct == EMMessage.Direct.RECEIVE ? 
					inflater.inflate(R.layout.row_received_video, null) : 
						inflater.inflate(R.layout.row_sent_video, null);
		case FILE:
			return message.direct == EMMessage.Direct.RECEIVE ? 
					inflater.inflate(R.layout.row_received_file, null) : 
						inflater.inflate(R.layout.row_sent_file, null);

		default:
			return message.direct == EMMessage.Direct.RECEIVE ? 
					inflater.inflate(R.layout.row_received_message, null) : 
						inflater.inflate(R.layout.row_sent_message, null);
		}
	}
	
	private void handleImageMessage(final EMMessage message, final ViewHolder holder, 
			final int position, View convertView) {
		holder.pb.setTag(position);
		holder.iv.setOnLongClickListener(new OnLongClickListener() {
			public boolean onLongClick(View v) {
				Intent intent = new Intent(activity, ContextMenuActivity.class);
				intent.putExtra(IntentString.Extra.ALERT_POSITION, position);
				intent.putExtra(IntentString.Extra.TYPE, EMMessage.Type.IMAGE.ordinal());
				activity.startActivityForResult(intent, IntentString.RequestCode.CHAT_CONTEXTMENU);
				return true;
			}
		});

		if (message.direct == EMMessage.Direct.RECEIVE) {
			System.err.println("it is receive msg");
			if (message.status == EMMessage.Status.INPROGRESS) {
				System.err.println("!!!! back receive");
				holder.iv.setImageResource(R.drawable.default_image);
				showDownloadImageProgress(message, holder);
				//downloadImage(message, holder);
			} else {
				System.err.println("!!!! not back receive, show image directly");
				holder.pb.setVisibility(View.GONE);
				holder.tv.setVisibility(View.GONE);
				holder.iv.setImageResource(R.drawable.default_image);
				ImageMessageBody imgBody = (ImageMessageBody) message.getBody();
				if (imgBody.getLocalUrl() != null) {
					String filePath = imgBody.getLocalUrl();
					String thumbnailPath = ImageUtils.getThumbnailImagePath(filePath);
					showImageView(thumbnailPath, holder.iv, filePath, imgBody.getRemoteUrl(), message);
				}
			}
			return;
		}

		// process send message
		System.err.println("!!!! it is send msg");
		// send pic, show the pic directly
		ImageMessageBody imgBody = (ImageMessageBody) message.getBody();
		String filePath = imgBody.getLocalUrl();
		if (new File(filePath).exists())
			showImageView(ImageUtils.getThumbnailImagePath(filePath), holder.iv, filePath, null, message);
		else {
			showImageView(ImageUtils.getThumbnailImagePath(filePath), holder.iv, 
					filePath, NormalString.File.IMAGE_DIR, message);
		}

		switch (message.status) {
		case SUCCESS:
			holder.pb.setVisibility(View.GONE);
			holder.tv.setVisibility(View.GONE);
			holder.staus_iv.setVisibility(View.GONE);
			break;
		case FAIL:
			holder.pb.setVisibility(View.GONE);
			holder.tv.setVisibility(View.GONE);
			holder.staus_iv.setVisibility(View.VISIBLE);
			break;
		case INPROGRESS:
			// set a timer
			final Timer timer = new Timer();
			timer.schedule(new TimerTask() {
				public void run() {
					activity.runOnUiThread(new Runnable() {
						public void run() {
							holder.pb.setVisibility(View.VISIBLE);
							holder.tv.setVisibility(View.VISIBLE);
							holder.tv.setText(message.progress + "%");
							if (message.status == EMMessage.Status.SUCCESS) {
								holder.pb.setVisibility(View.GONE);
								holder.tv.setVisibility(View.GONE);
								// message.setSendingStatus(Message.SENDING_STATUS_SUCCESS);
								timer.cancel();
							} else if (message.status == EMMessage.Status.FAIL) {
								holder.pb.setVisibility(View.GONE);
								holder.tv.setVisibility(View.GONE);
								// message.setSendingStatus(Message.SENDING_STATUS_FAIL);
								// message.setProgress(0);
								holder.staus_iv.setVisibility(View.VISIBLE);
								ToastUtil.prompt(activity, "发送消息失败，连接不到服务器，请稍后重试");
								timer.cancel();
							}
						}
					});

				}
			}, 0, 500);
			break;
		default:
			sendPictureMessage(message, holder);
		}
	}
	
	private void handleVoiceMessage(final EMMessage message, final ViewHolder holder, 
			final int position, View convertView) {
		VoiceMessageBody voiceBody = (VoiceMessageBody) message.getBody();
		holder.tv.setText(voiceBody.getLength() + "\"");
		VoicePlayClickListener listener = new VoicePlayClickListener(message, holder.iv, 
				holder.iv_read_status, activity, activity, friendId);
		holder.iv.setOnClickListener(listener);
		holder.iv.setOnLongClickListener(new OnLongClickListener() {
			public boolean onLongClick(View v) {
				Intent intent = new Intent(activity, ContextMenuActivity.class);
				intent.putExtra(IntentString.Extra.ALERT_POSITION, position);
				intent.putExtra(IntentString.Extra.TYPE, EMMessage.Type.VOICE.ordinal());
				activity.startActivityForResult(intent, IntentString.RequestCode.CHAT_CONTEXTMENU);
				return true;
			}
		});

		if (message.direct == EMMessage.Direct.RECEIVE) {
			if (message.isAcked) {
				// 隐藏语音未读标志
				holder.iv_read_status.setVisibility(View.INVISIBLE);
			} else {
				holder.iv_read_status.setVisibility(View.VISIBLE);
			}
			return;
		}

		// until here, deal with send voice msg
		switch (message.status) {
		case SUCCESS:
			holder.pb.setVisibility(View.GONE);
			holder.staus_iv.setVisibility(View.GONE);
			break;
		case FAIL:
			holder.pb.setVisibility(View.GONE);
			holder.staus_iv.setVisibility(View.VISIBLE);
			break;
		case INPROGRESS:
			break;
		default:
			sendMsgInBackground(message, holder);
		}
	}
	
	private void handleVideoMessage(final EMMessage message, final ViewHolder holder, 
			final int position, View convertView) {

		VideoMessageBody videoBody = (VideoMessageBody) message.getBody();
		// final File image=new File(PathUtil.getInstance().getVideoPath(),
		// videoBody.getFileName());
		String localThumb = videoBody.getLocalThumb();
		holder.iv.setOnLongClickListener(new OnLongClickListener() {
			public boolean onLongClick(View v) {
				Intent intent = new Intent(activity, ContextMenuActivity.class);
				intent.putExtra(IntentString.Extra.ALERT_POSITION, position);
				intent.putExtra(IntentString.Extra.TYPE, EMMessage.Type.VIDEO.ordinal());
				activity.startActivityForResult(intent, IntentString.RequestCode.CHAT_CONTEXTMENU);
				return true;
			}
		});

		if (localThumb != null) {
			showVideoThumbView(localThumb, holder.iv, videoBody.getThumbnailUrl(), message);
		}
		if (videoBody.getLength() > 0) {
			String time = DateUtils.toTimeBySecond(videoBody.getLength());
			holder.timeLength.setText(time);
		}
		holder.playBtn.setImageResource(R.drawable.video_download_btn_nor);

		if (message.direct == EMMessage.Direct.RECEIVE) {
			if (videoBody.getVideoFileLength() > 0) {
				String size = TextFormater.getDataSize(videoBody.getVideoFileLength());
				holder.size.setText(size);
			}
		} else {
			if (videoBody.getLocalUrl() != null && new File(videoBody.getLocalUrl()).exists()) {
				String size = TextFormater.getDataSize(new File(videoBody.getLocalUrl()).length());
				holder.size.setText(size);
			}
		}

		if (message.direct == EMMessage.Direct.RECEIVE) {

			System.err.println("it is receive msg");
			if (message.status == EMMessage.Status.INPROGRESS) {
				System.err.println("!!!! back receive");
				holder.iv.setImageResource(R.drawable.default_image);
				showDownloadImageProgress(message, holder);

			} else {
				System.err.println("!!!! not back receive, show image directly");
				holder.iv.setImageResource(R.drawable.default_image);
				if (localThumb != null) {
					showVideoThumbView(localThumb, holder.iv, videoBody.getThumbnailUrl(), message);
				}
			}
			return;
		}
		holder.pb.setTag(position);

		// until here ,deal with send video msg
		switch (message.status) {
		case SUCCESS:
			holder.pb.setVisibility(View.GONE);
			holder.staus_iv.setVisibility(View.GONE);
			holder.tv.setVisibility(View.GONE);
			break;
		case FAIL:
			holder.pb.setVisibility(View.GONE);
			holder.tv.setVisibility(View.GONE);
			holder.staus_iv.setVisibility(View.VISIBLE);
			break;
		case INPROGRESS:
			// set a timer
			final Timer timer = new Timer();
			timer.schedule(new TimerTask() {

				@Override
				public void run() {
					activity.runOnUiThread(new Runnable() {

						@Override
						public void run() {
							holder.pb.setVisibility(View.VISIBLE);
							holder.tv.setVisibility(View.VISIBLE);
							holder.tv.setText(message.progress + "%");
							if (message.status == EMMessage.Status.SUCCESS) {
								holder.pb.setVisibility(View.GONE);
								holder.tv.setVisibility(View.GONE);
								// message.setSendingStatus(Message.SENDING_STATUS_SUCCESS);
								timer.cancel();
							} else if (message.status == EMMessage.Status.FAIL) {
								holder.pb.setVisibility(View.GONE);
								holder.tv.setVisibility(View.GONE);
								// message.setSendingStatus(Message.SENDING_STATUS_FAIL);
								// message.setProgress(0);
								holder.staus_iv.setVisibility(View.VISIBLE);
								ToastUtil.prompt(activity, "发送消息失败，连接不到服务器，请稍后重试");
								timer.cancel();
							}
						}
					});
				}
			}, 0, 500);
			break;
		default:
			// sendMsgInBackground(message, holder);
			sendPictureMessage(message, holder);
		}
	}
	
	private void showVideoThumbView(String localThumb, ImageView iv, String thumbnailUrl, final EMMessage message) {
		// first check if the thumbnail image already loaded into cache
		Bitmap bitmap = ImageCache.getInstance().get(localThumb);
		if (bitmap != null) {
			// thumbnail image is already loaded, reuse the drawable
			iv.setImageBitmap(bitmap);
			iv.setClickable(true);
			iv.setOnClickListener(new View.OnClickListener() {

				@Override
				public void onClick(View v) {
					VideoMessageBody videoBody = (VideoMessageBody) message.getBody();
					System.err.println("video view is on click");
					Intent intent = new Intent(activity, ShowVideoActivity.class);
					intent.putExtra("localpath", videoBody.getLocalUrl());
					intent.putExtra("secret", videoBody.getSecret());
					intent.putExtra("remotepath", videoBody.getRemoteUrl());
					if (message != null && message.direct == EMMessage.Direct.RECEIVE && !message.isAcked
							&& message.getChatType() != ChatType.GroupChat) {
						message.isAcked = true;
						try {
							EMChatManager.getInstance().ackMessageRead(message.getFrom(), message.getMsgId());
						} catch (Exception e) {
							e.printStackTrace();
						}
					}
					activity.startActivity(intent);

				}
			});

		} else {
			new LoadVideoImageTask().execute(localThumb, thumbnailUrl, iv,activity, message,this);
		}
	}
	
	private void handleFileMessage(final EMMessage message, final ViewHolder holder, int position, View convertView) {
		final NormalFileMessageBody fileMessageBody = (NormalFileMessageBody) message.getBody();
		final String filePath = fileMessageBody.getLocalUrl();
		holder.tv_file_name.setText(fileMessageBody.getFileName());
		holder.tv_file_size.setText(TextFormater.getDataSize(fileMessageBody.getFileSize()));
		holder.ll_container.setOnClickListener(new OnClickListener() {
			public void onClick(View view) {
				File file = new File(filePath);
				if(file != null && file.exists()){
					//文件存在，直接打开
					FileUtils.openFile(file, activity);
				}else{
					//下载
					Intent intent = new Intent(activity, ShowNormalFileActivity.class);
					intent.putExtra("msgbody", fileMessageBody);
					activity.startActivity(intent);
				}
				if(message.direct == EMMessage.Direct.RECEIVE && !message.isAcked){
					try {
						EMChatManager.getInstance().ackMessageRead(message.getFrom(), message.getMsgId());
						message.isAcked = true;
					} catch (EaseMobException e) {
						e.printStackTrace();
					}
				}
			}
		});

		if (message.direct == EMMessage.Direct.RECEIVE) { // 接收的消息
			System.err.println("it is receive msg");
			File file = new File(filePath);
			if(file != null && file.exists()){
				holder.tv_file_download_state.setText("已下载");
			}else{
				holder.tv_file_download_state.setText("未下载");
			}
			return;
		}

		// until here, deal with send voice msg
		switch (message.status) {
		case SUCCESS:
			holder.pb.setVisibility(View.INVISIBLE);
			holder.staus_iv.setVisibility(View.INVISIBLE);
			break;
		case FAIL:
			holder.pb.setVisibility(View.INVISIBLE);
			holder.staus_iv.setVisibility(View.VISIBLE);
			break;
		case INPROGRESS:
			// set a timer
			final Timer timer = new Timer();
			timer.schedule(new TimerTask() {

				@Override
				public void run() {
					activity.runOnUiThread(new Runnable() {

						@Override
						public void run() {
							holder.pb.setVisibility(View.VISIBLE);
							// holder.tv.setVisibility(View.VISIBLE);
							// holder.tv.setText(message.progress + "%");
							if (message.status == EMMessage.Status.SUCCESS) {
								holder.pb.setVisibility(View.INVISIBLE);
								// holder.tv.setVisibility(View.GONE);
								// message.setSendingStatus(Message.SENDING_STATUS_SUCCESS);
								timer.cancel();
							} else if (message.status == EMMessage.Status.FAIL) {
								holder.pb.setVisibility(View.INVISIBLE);
								// holder.tv.setVisibility(View.GONE);
								// message.setSendingStatus(Message.SENDING_STATUS_FAIL);
								// message.setProgress(0);
								holder.staus_iv.setVisibility(View.VISIBLE);
								ToastUtil.prompt(activity, "发送消息失败，连接不到服务器，请稍后重试");
								timer.cancel();
							}
						}
					});
				}
			}, 0, 500);
			break;
		default:
			sendMsgInBackground(message, holder);
		}
	}
	
	private void handleLocationMessage(final EMMessage message, final ViewHolder holder, 
			final int position, View convertView) {
		TextView locationView = ((TextView) convertView.findViewById(R.id.tv_location));
		LocationMessageBody locBody = (LocationMessageBody) message.getBody();
		locationView.setText(locBody.getAddress());
		LatLng loc = new LatLng(locBody.getLatitude(), locBody.getLongitude());
		locationView.setOnClickListener(new MapClickListener(loc, locBody.getAddress()));
		locationView.setOnLongClickListener(new OnLongClickListener() {
			@Override
			public boolean onLongClick(View v) {
				Intent intent = new Intent(activity, ContextMenuActivity.class);
				intent.putExtra(IntentString.Extra.ALERT_POSITION, position);
				intent.putExtra(IntentString.Extra.TYPE, EMMessage.Type.LOCATION.ordinal());
				activity.startActivityForResult(intent, IntentString.RequestCode.CHAT_CONTEXTMENU);
				return false;
			}
		});

		if (message.direct == EMMessage.Direct.RECEIVE) {
			return;
		}
		// deal with send message
		switch (message.status) {
		case SUCCESS:
			holder.pb.setVisibility(View.GONE);
			holder.staus_iv.setVisibility(View.GONE);
			break;
		case FAIL:
			holder.pb.setVisibility(View.GONE);
			holder.staus_iv.setVisibility(View.VISIBLE);
			break;
		case INPROGRESS:
			break;
		default:
			sendMsgInBackground(message, holder);
		}
	}
	
	private void handleTextMessage(EMMessage message, ViewHolder holder, final int position) {
		TextMessageBody txtBody = (TextMessageBody) message.getBody();
		SpannableString spannableString = new SpannableString(txtBody.getMessage());
		spannableString = StringUtil.spanExp(activity, spannableString, txtBody.getMessage());
		holder.tv.setText(spannableString);
		holder.tv.setOnLongClickListener(new OnLongClickListener() {
			public boolean onLongClick(View v) {
				Intent intent = new Intent(activity, ContextMenuActivity.class);
				intent.putExtra(IntentString.Extra.ALERT_POSITION, position);
				intent.putExtra(IntentString.Extra.TYPE, EMMessage.Type.TXT.ordinal());
				activity.startActivityForResult(intent, IntentString.RequestCode.CHAT_CONTEXTMENU);
				return true;
			}
		});
		if (message.direct == EMMessage.Direct.SEND) {
			switch (message.status) {
			case SUCCESS:
				holder.pb.setVisibility(View.GONE);
				holder.staus_iv.setVisibility(View.GONE);
				break;
			case FAIL:
				holder.pb.setVisibility(View.GONE);
				holder.staus_iv.setVisibility(View.VISIBLE);
				break;
			case INPROGRESS:
				break;
			default:
				sendMsgInBackground(message, holder);
			}
		}
	}
	
	public void sendMsgInBackground(final EMMessage message, final ViewHolder holder) {
		holder.staus_iv.setVisibility(View.GONE);
		holder.pb.setVisibility(View.VISIBLE);
		EMChatManager.getInstance().sendMessage(message, new EMCallBack() {
			public void onSuccess() {
				updateSendedView(message, holder);
			}
			public void onError(int code, String error) {
				updateSendedView(message, holder);
			}
			public void onProgress(int progress, String status) {
				
			}
		});
	}
	
	private void showDownloadImageProgress(final EMMessage message, final ViewHolder holder) {
		System.err.println("!!! show download image progress");
		// final ImageMessageBody msgbody = (ImageMessageBody)
		// message.getBody();
		final FileMessageBody msgbody = (FileMessageBody) message.getBody();
		msgbody.setDownloadCallback(new EMCallBack() {
			public void onSuccess() {
				activity.runOnUiThread(new Runnable() {
					public void run() {
						// message.setBackReceive(false);
						if (message.getType() == EMMessage.Type.IMAGE) {
							holder.pb.setVisibility(View.GONE);
							holder.tv.setVisibility(View.GONE);
						}
						notifyDataSetChanged();
					}
				});
			}
			public void onError(int code, String message) {

			}
			public void onProgress(final int progress, String status) {
				if (message.getType() == EMMessage.Type.IMAGE) {
					activity.runOnUiThread(new Runnable() {
						public void run() {
							holder.tv.setText(progress + "%");
						}
					});
				}
			}
		});
	}
	
	private void sendPictureMessage(final EMMessage message, final ViewHolder holder) {
		try {
			@SuppressWarnings("unused")
			String to = message.getTo();
			// before send, update ui
			holder.staus_iv.setVisibility(View.GONE);
			holder.pb.setVisibility(View.VISIBLE);
			holder.tv.setVisibility(View.VISIBLE);
			holder.tv.setText("0%");
			EMChatManager.getInstance().sendMessage(message, new EMCallBack() {
				public void onSuccess() {
					Log.d(TAG, "send image message successfully");
					activity.runOnUiThread(new Runnable() {
						public void run() {
							// send success
							holder.pb.setVisibility(View.GONE);
							holder.tv.setVisibility(View.GONE);
						}
					});
				}
				public void onError(int code, String error) {
					activity.runOnUiThread(new Runnable() {
						public void run() {
							holder.pb.setVisibility(View.GONE);
							holder.tv.setVisibility(View.GONE);
							// message.setSendingStatus(Message.SENDING_STATUS_FAIL);
							holder.staus_iv.setVisibility(View.VISIBLE);
							ToastUtil.prompt(activity, "发送消息失败，连接不到服务器，请稍后重试");
						}
					});
				}
				public void onProgress(final int progress, String status) {
					activity.runOnUiThread(new Runnable() {
						public void run() {
							holder.tv.setText(progress + "%");
						}
					});
				}
			});
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private void updateSendedView(final EMMessage message, final ViewHolder holder) {
		activity.runOnUiThread(new Runnable() {
			public void run() {
				// message.setBackSend(false);
				// send success
				if (message.status == EMMessage.Status.SUCCESS) {
					holder.pb.setVisibility(View.GONE);
					holder.staus_iv.setVisibility(View.GONE);
				} else if (message.status == EMMessage.Status.FAIL) {
					holder.pb.setVisibility(View.GONE);
					holder.staus_iv.setVisibility(View.VISIBLE);
					ToastUtil.prompt(activity, "发送消息失败，连接不到服务器，请稍后重试");
				}
			}
		});
	}
	
	private boolean showImageView(final String thumbernailPath, final ImageView iv, 
			final String localFullSizePath, String remoteDir, final EMMessage message) {
		@SuppressWarnings("unused")
		String imagename = localFullSizePath.substring(localFullSizePath.lastIndexOf("/") + 1, 
				localFullSizePath.length());
		// final String remote = remoteDir != null ? remoteDir+imagename :
		// imagename;
		final String remote = remoteDir;

		// first check if the thumbnail image already loaded into cache
		Bitmap bitmap = ImageCache.getInstance().get(thumbernailPath);
		if (bitmap != null) {
			// thumbnail image is already loaded, reuse the drawable
			iv.setImageBitmap(bitmap);
			iv.setClickable(true);
			iv.setOnClickListener(new View.OnClickListener() {
				@Override
				public void onClick(View v) {
					System.err.println("image view on click");
					Intent intent = new Intent(activity, ShowBigImageActivity.class);
					File file = new File(localFullSizePath);
					if (file.exists()) {
						Uri uri = Uri.fromFile(file);
						intent.putExtra("uri", uri);
						System.err.println("here need to check why download everytime");
					} else {
						// The local full size pic does not exist yet.
						// ShowBigImage needs to download it from the server
						// first
						// intent.putExtra("", message.get);
						ImageMessageBody body = (ImageMessageBody) message.getBody();
						intent.putExtra("secret", body.getSecret());
						intent.putExtra("remotepath", remote);
					}
					if (message != null && message.direct == EMMessage.Direct.RECEIVE && !message.isAcked
							&& message.getChatType() != ChatType.GroupChat) {
						message.isAcked = true;
						try {
							EMChatManager.getInstance().ackMessageRead(message.getFrom(), message.getMsgId());
						} catch (Exception e) {
							e.printStackTrace();
						}
					}
					activity.startActivity(intent);
				}
			});
			return true;
		} else {
			new LoadImageTask().execute(thumbernailPath, localFullSizePath, 
					remote, message.getChatType(), iv, activity, message);
			return true;
		}
	}
	
	class MapClickListener implements View.OnClickListener {
		
		LatLng location;
		String address;
		
		public MapClickListener(LatLng loc, String address) {
			location = loc;
			this.address = address;
		}

		public void onClick(View v) {
			Intent intent;
			intent = new Intent(activity, BaiduMapActivity.class);
			intent.putExtra("latitude", location.latitude);
			intent.putExtra("longitude", location.longitude);
			intent.putExtra("address", address);
			activity.startActivity(intent);
		}
	}

}
